#ifndef __tenacitas_log__change_file_notifier__h__
#define __tenacitas_log__change_file_notifier__h__


/** @file Declaration of tenacitas::log::change_file_notifier */

/** @todo Improve documentation */

// ==> C++ Headers
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

// ==> 3rds Headers
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>

// ==> Our Headers
#include <tenacitas.exception/exception.h>
#include <tenacitas.boost_tools/utils.h>

// ==> Namespaces
using namespace std;

// ==> Macro Contants

// ==> Macro Commands


/** namespace of the organization */
namespace tenacitas {
    /** namespace for the project */
    namespace log {


        // ==> Typedefs 

        // ==> Pre-Declarations

        // ==> Attributes 

        // ==> Functions
        
        // ==> Classes

        /** A simple way for deciding when log messages should start to be
            recording in a new log file

            This class informs when a log file should be changed based on its
            size. 

            <b>A word to the programmer user</b>
            You should call static method @p config to define the maximum size of
            the log file, before a new one is generated. 
            That is it! The @p tenacitas::log::file class that will use this
            @p change_file_notifier class will call the other necessary
            methods
            @nosubgrouping
        */
        class change_file_notifier {

        public:

            // ==> change_file_notifier - Public Internal Types

            /** Pointer to a @p change_file_notifier object */
            typedef boost::shared_ptr<change_file_notifier> ptr;

            // ==> change_file_notifier - Public Constructors

            /** Defines data for creating every @p change_file_notifier
                objects

                @param  p_max_file_size is the maximum size that a log file can
                reach, before a new log file is created
            */
            inline static void config( uint64_t p_max_file_size =
                                       1024 * 1014 * 10 ); 


            /** Destructor */
            inline ~change_file_notifier( );

            /** not-allowed */
            change_file_notifier( const change_file_notifier & ) =
                delete;

            /** not-allowed */
            change_file_notifier( change_file_notifier && ) =
                delete;


            /** Creates a reference to a @p change_file_notifier policy */
            static ptr create( ) {
                return ptr( new change_file_notifier( ) );
            }
            
            
            // ==> change_file_notifier - Public Processors

            /** Informs if a new log file should be created

                @param  p_file_size is the current log file size
            */
            inline bool change_now( uint64_t p_file_size ) const;


            // ==> change_file_notifier - Public Operators

            /** not-allowed */
            change_file_notifier & operator=( const change_file_notifier & ) =
                delete;

            /** not-allowed */
            change_file_notifier & operator=( change_file_notifier && ) =
                delete;

        private:

            // ==> change_file_notifier - Private Constructors

            /** Creates a new @p change_file_notifier object */
            inline change_file_notifier( );

            // ==> change_file_notifier - Private Attributes

            /** maximum log file size, before it is changed */
            static uint64_t m_max_file_size;
        };
    }
}

// =============================================================================
// I M P L E M E N T A T I O N
// =============================================================================


using namespace tenacitas::log;

// -----------------------------------------------------------------------------
change_file_notifier::
~change_file_notifier( ) {}

// -----------------------------------------------------------------------------
change_file_notifier::
change_file_notifier( ) {}

// -----------------------------------------------------------------------------
void
change_file_notifier::
config( uint64_t p_max_file_size ) {
    m_max_file_size = p_max_file_size;
}


// -----------------------------------------------------------------------------
bool
change_file_notifier::
change_now( uint64_t p_file_size ) const {
    static const double ninety_per_cent_max =
        0.9 * static_cast<double>( m_max_file_size );

    return ( static_cast<double>( p_file_size ) > ninety_per_cent_max );
}

#endif
